package com.cy.pj.sys.service.impl;

import com.cy.pj.sys.advice.ServiceException;
import com.cy.pj.sys.common.annotation.RequiredLog;
import com.cy.pj.sys.dao.SysLogDao;
import com.cy.pj.sys.pojo.SysLog;
import com.cy.pj.sys.service.SysLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
@Service
@Transactional(readOnly = false,timeout = 60,rollbackFor = Throwable.class
            ,isolation = Isolation.READ_COMMITTED//事务级别
)
public class SysLogServiceImpl implements SysLogService {

    @Autowired
    private SysLogDao sysLogDao;



    @Override
   // @RequiredTime(operation = "条件查询!!!!!!!!")
    @RequiredLog(operation = "条件查询")
    public List<SysLog> selectLogs(SysLog sysLog) {
        System.out.println("selectLogs: "+Thread.currentThread().getName());
        List<SysLog> list =  sysLogDao.selectLogs(sysLog);
        return list;
    }

    @RequiredLog(operation = "ID查询")
    @Override
    public SysLog selectById(Long id) {

            SysLog sysLog = sysLogDao.selectById(id);
            if (sysLog==null)
                throw new ServiceException("sysLog为空!!!!!");
            return sysLog;



    }

    @Async
    @Override
    public void insertLog(SysLog sysLog) {
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        sysLogDao.insertLog(sysLog);
    }

//    @Async//@Async注解描述的方法为一个异步切入点方法,这个方法执行时底层会在新的线程中进行调用
//    @Override
//    public Future<Integer> insertLog(SysLog sysLog) {
//        System.out.println("insertLog: "+Thread.currentThread().getName());
//        try {
//            Thread.sleep(10000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//        int i = sysLogDao.insertLog(sysLog);
//        return new AsyncResult<>(i);
//    }

    //spring中的事务管理,默认是使用切面方式进行的,底层依然会生成代理对象,织入事务功能
    //具体可以看DataSourceTransactionManager类
    //描述的业务类和方法
    @Transactional()//此注解描述方法时,这个方法为一个事务切入点方法
    @RequiredLog(operation = "删除操作")
    @Override
    public int deleteById(Long... ids) {
   //     Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();

       //try{
            int i = sysLogDao.deleteById(ids);
      //    SysLog sysLog = this.selectById(88L);
        /*
         * SysLog sysLog = this.selectById(88L);
         * 但在需要事务控制的方法中,调用本类的其他方法.由于该类需要Spring进行事务控制,会生成代理类,
         * 如果是通过jdk进行动态代理生成的代理类,那么在该方法中通过this.selectById(88L)调用的方法
         * 实际上是调用了原生类中的方法,而不是代理类中的方法,那么该this的方法上的事务就不会实现,
         * 如果使用的是cglib代理生成的代理对象,因为cglib基于继承进行代理，this不会出现上述问题，
         * 但理论上调用私有方法时，子类对象是访问不到父类私有方法的。
         */

         //   throw new ServiceException("来了异常");

       //}catch (RuntimeException e){
           //  TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
      //     System.out.println("里面的执行了");
    //   }
          //  TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

        return i;
    }
}
